package com.wondertek.web.controller.business;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.github.pagehelper.PageInfo;
import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport;
import com.wondertek.common.base.Result;
import com.wondertek.common.exception.AppException;
import com.wondertek.common.log.AutoLogUtil;
import com.wondertek.common.util.security.PreAuthorize;
import com.wondertek.common.util.security.SecurityUtil;
import com.wondertek.service.dto.business.req.*;
import com.wondertek.service.dto.business.res.DeviceAllRes;
import com.wondertek.service.dto.business.res.DevicePageRes;
import com.wondertek.service.dto.business.res.SiteDeviceAccessoryRes;
import com.wondertek.service.dto.business.res.TimeZoneDictRes;
import com.wondertek.service.dto.sys.req.BaseUpdateReq;
import com.wondertek.service.entity.business.DevicePo;
import com.wondertek.service.entity.business.DeviceTypeDetailPo;
import com.wondertek.service.sdk.iotdh.dto.req.*;
import com.wondertek.service.sdk.iotdh.dto.req.utc.SetDeviceUTCTimezoneReq;
import com.wondertek.service.sdk.iotdh.dto.res.*;
import com.wondertek.service.sdk.iotdh.dto.res.network.AroundWirelessNetwork;
import com.wondertek.service.sdk.iotdh.dto.res.network.GetCurrentWirelessNetworkRes;
import com.wondertek.service.sdk.iotdh.service.DhDeviceService;
import com.wondertek.service.service.business.DeviceService;
import com.wondertek.service.service.business.DeviceTypeDetailService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.annotation.Resource;
import org.apache.commons.collections4.CollectionUtils;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import java.util.List;

/**
 * @description: 设备管理
 * @author: qinjianhui
 * @create: 2024-07-18 11:22
 **/
@RestController
@RequestMapping("/backend/business/device/")
@Tag(name = "设备管理")
public class DeviceController {

    @Resource
    private DeviceService deviceService;

    @Resource
    private DeviceTypeDetailService deviceTypeService;

    @Resource
    private DhDeviceService dhDeviceService;

    @PostMapping("/setNotAlarmDay")
    @Operation(summary = "设置未报警天数")
    public Result setNotAlarmDay(@RequestParam("deviceId") String deviceId, @RequestParam("notAlarmDay") Integer notAlarmDay) {
        DevicePo devicePo = new DevicePo();
        devicePo.setNotAlarmDay(notAlarmDay);
        devicePo.setId(deviceId);
        deviceService.updateById(devicePo);
        return Result.success();
    }

    @PostMapping("/getIpcList")
    @Operation(summary = "获取ipc列表")
    public Result<List<DevicePo>> getIpcList() {
        LambdaQueryWrapper<DevicePo> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(DevicePo::getDeviceTypeId, "62");
        List<DevicePo> list = deviceService.list(lambdaQueryWrapper);
        return Result.success(list);
    }

    @PostMapping("/getUpgradeVersionInfo")
    @Operation(summary = "搜索 Alarm Hub 的云更新版本")
    public Result<GetUpgradeVersionInfoRes> getUpgradeVersionInfo(@RequestBody @Validated ComId req) {
        return dhDeviceService.getUpgradeVersionInfo(req);
    }

    @PostMapping("/deviceVersionList")
    @Operation(summary = "获取设备版本和可升级信息")
    public Result<DeviceVersionListRes> deviceVersionList(@RequestBody @Validated DeviceVersionListReq req) {
        return dhDeviceService.deviceVersionList(req);
    }

    @PostMapping("/upgradeDevice")
    @Operation(summary = "设备升级")
    public Result<?> upgradeDevice(@RequestBody @Validated VerifyDevCodeReq req) {

        if(deviceService.findModeByDeviceSn(req.getDeviceId()) > 0)
            throw new AppException("Some areas are armed, can not operate");

        dhDeviceService.upgradeDevice(req);
        //同时将设备下线下线
        LambdaQueryWrapper<DevicePo> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(DevicePo::getSnCode,req.getDeviceId());
        List<DevicePo> list = deviceService.list(lambdaQueryWrapper);
        if(CollectionUtils.isNotEmpty(list)){
            DevicePo devicePo = list.get(0);
            devicePo.setStatus(0);
            deviceService.updateById(devicePo);
        }
        return Result.success();
    }

    @PostMapping("/getUpgradeProgress")
    @Operation(summary = "搜索Alarm Hub的云更新进度")
    public Result<GetUpgradeProgressRes> getUpgradeProgress(@RequestBody @Validated ComId req) {
        return dhDeviceService.getUpgradeProgress(req);
    }

    @PostMapping("/typeSelect")
    @Operation(summary = "查询设备类型")
    public Result<List<DeviceTypeDetailPo>> typeSelect() {
        LambdaQueryWrapper<DeviceTypeDetailPo> wrapper = new LambdaQueryWrapper<>();
        wrapper.apply("category is not null and category!=''");
        return Result.success(deviceTypeService.list(wrapper));
    }

    @PostMapping("/add")
    @Operation(summary = "新增设备")
    @PreAuthorize("@el.check('backend:business:device:add')")
    public Result<?> addDevice(@RequestBody @Validated DeviceAddReq deviceAddReq) {
        deviceService.addDevice(deviceAddReq);
        return Result.success();
    }


    @PostMapping("/delete")
    @Operation(summary = "删除设备")
    @PreAuthorize("@el.check('backend:business:device:delete')")
    public Result<?> deleteDevice(@RequestBody @Validated BaseUpdateReq baseUpdateReq) {
        deviceService.deleteDevice(baseUpdateReq.getId());
        return Result.success();
    }

    @PostMapping("/page")
    @Operation(summary = "查询设备")
    @PreAuthorize("@el.check('backend:business:device:page')")
    public Result<PageInfo<DevicePageRes>> page(@RequestBody DevicePageReq devicePageReq) {
        return Result.success(deviceService.page(devicePageReq));
    }

    @PostMapping("/exportDevice")
    @Operation(summary = "导出设备")
    public void exportDevice(@RequestBody DevicePageReq devicePageReq, HttpServletResponse response) {

        deviceService.exportDevice(devicePageReq, response);
    }

    @PostMapping("/update")
    @Operation(summary = "修改设备")
    @PreAuthorize("@el.check('backend:business:device:update')")
    public Result<?> updateDevice(@RequestBody @Validated DeviceUpdateReq updateReq) {
        deviceService.updateDevice(updateReq);
        return Result.success();
    }

    @GetMapping("/findAllGatewayBySiteId")
    @Operation(summary = "根据站点id查询所有网关设备")
    public Result<List<DeviceAllRes>> findAllGatewayBySiteId(@RequestParam("siteId") String siteId) {
        return Result.success(deviceService.findAllGatewayBySiteId(siteId));
    }

    @PostMapping("/findAllGateway")
    @Operation(summary = "查询所有网关设备")
    public Result<List<DeviceAllRes>> findAllGateway(@RequestBody BaseUpdateReq req) {
        String id = SecurityUtil.getLoginUser().getUserId();
        return Result.success(deviceService.findAllGateway(req.getId(), id));
    }

    @PostMapping("/ipc/detail")
    @Operation(summary = "查询ipc设备详情")
    public Result<String> ipcDetail(@RequestBody @Validated StreamUrlAddDhReq req) {
        return dhDeviceService.addStreamUrl(req);
    }

    @PostMapping("/ipc/localRecords")
    @Operation(summary = "查询ipc回放列表")
    public Result<List<LocalRecordRes>> ipcLocalRecords(@RequestBody @Validated LocalRecordsReq req) {
        Result<List<LocalRecordRes>> res = dhDeviceService.LocalRecords(req);
        List<LocalRecordRes> list = res.getData();
        List<LocalRecordRes> list1 = getLocalRecords(list, req.getEndTime(), req.getDeviceSn());
        return Result.success(list1);
    }

    private List<LocalRecordRes> getLocalRecords(List<LocalRecordRes> list, String endTime, String deviceSn) {
        if (CollectionUtils.isNotEmpty(list) && (list.size() % 64 == 0 || list.size() % 63==1)) {
            String startTime = list.get(list.size() - 1).getEndTime();
            LocalRecordsReq req = new LocalRecordsReq();
            req.setBeginTime(startTime);
            req.setEndTime(endTime);
            req.setCount("64");
            req.setDeviceSn(deviceSn);
            Result<List<LocalRecordRes>> res = dhDeviceService.LocalRecords(req);
            List<LocalRecordRes> list1 = res.getData();
            if (CollectionUtils.isNotEmpty(list1)) {
                list.remove(list.size() - 1);
                list.addAll(list1);
                this.getLocalRecords(list, endTime, deviceSn);
            }
        }
        return list;
    }

    @PostMapping("/network/detail")
    @Operation(summary = "查询网关设备详情")
    public Result<GetStatusRes> networkDetail(@RequestBody @Validated GetStatusReq req) {
        return dhDeviceService.getStatus(req);
    }

    @PostMapping("/network/set/detail")
    @Operation(summary = "查询网关设备开关详情")
    public Result<?> setDetail(@RequestBody @Validated GetEnableReq req) {
        return dhDeviceService.getEnable(req);
    }

    @PostMapping("/network/set")
    @Operation(summary = "网关开关设置")
    public Result<?> set(@RequestBody @Validated SetEnableReq req) {
        DevicePo devicePo = new DevicePo();
        devicePo.setSnCode(req.getDeviceId());
        SiteDeviceAccessoryRes res = deviceService.selectSiteDevice(devicePo);
        AutoLogUtil.save("sys", "log.gateway.switch.set", "网关sn码:" + req.getDeviceId(),
                res.getSiteName(), res.getDeviceSn(), res.getSiteId(), null);
        return dhDeviceService.setEnable(req);
    }

    @PostMapping("/network/set/mode")
    @Operation(summary = "网关设置布防")
    public Result NetworkSetMode(@RequestBody DeviceNetworkSetModeReq req) {
        deviceService.networkSetMode(req);
        return Result.success();
    }

    @GetMapping("/deviceRestart")
    @Operation(summary = "设备重启")
    public Result deviceRestart(@RequestParam("deviceSn") String deviceSn) {
        deviceService.deviceRestart(deviceSn);
        return Result.success();
    }

    /**
     * 查询时区字典
     *
     * @return
     */
    @GetMapping("/findTimeZoneDict")
    @Operation(summary = "查询时区字典")
    public Result<List<TimeZoneDictRes>> findTimeZoneDict(String search) {
        return Result.success(deviceService.findTimeZoneDict(search));
    }

    @GetMapping("/findDeviceTimeZone")
    @Operation(summary = "搜索设备时区")
    public Result<TimeZoneDictRes> findDeviceTimeZone(@RequestParam("deviceSn") String deviceSn) {

        return Result.success(deviceService.findDeviceTimeZone(deviceSn));
    }

    /**
     * 设置报警网关所在时区
     *
     * @param req
     */
    @PostMapping("/setDeviceUTCTimezone")
    @Operation(summary = "设置报警网关所在时区")
    public Result setDeviceUTCTimezone(@RequestBody @Validated SetDeviceUTCTimezoneReq req) {
        deviceService.setDeviceUTCTimezone(req);
        return Result.success();
    }

    /**
     * 修改网关设备密码
     *
     * @param req
     */
    @PostMapping("/modifyDevicePassword")
    @Operation(summary = "修改网关设备密码")
    public Result modifyDevicePassword(@RequestBody @Validated ModifyDevicePasswordReq req) {
        deviceService.modifyDevicePassword(req);
        return Result.success();
    }

    @GetMapping("/modifyDevicePasswordCheck")
    @Operation(summary = "点击网关设备密码修改校验")
    public Result modifyDevicePasswordCheck(@RequestParam("deviceSn") String deviceSn) {
        if (deviceService.findModeByDeviceSn(deviceSn) > 0)
            throw new AppException("Some areas are armed, can not operate");

        return Result.success();
    }

    /**
     * 配置有线网络
     *
     * @param networkInfoReq
     */
    @PostMapping("/setNetworkInfo")
    @Operation(summary = "配置有线网络")
    public Result setNetworkInfo(@RequestBody @Validated NetworkInfoReq networkInfoReq) {
        deviceService.setNetworkInfo(networkInfoReq);
        return Result.success();
    }


    /**
     * 查询有线网络
     *
     * @param deviceSn
     * @return
     */
    @GetMapping("/findNetworkInfo")
    @Operation(summary = "查询有线网络")
    public Result<NetworkInfoReq> findNetworkInfo(@RequestParam("deviceSn") String deviceSn) {
        return Result.success(deviceService.findNetworkInfo(deviceSn));
    }

    /**
     * 查询网关正在使用的wifi信息
     *
     * @param deviceSn
     * @return
     */
    @GetMapping("/findUseWifi")
    @Operation(summary = "查询网关正在使用的wifi信息")
    public Result<GetCurrentWirelessNetworkRes> findUseWifi(@RequestParam("deviceSn") String deviceSn) {
        return Result.success(deviceService.findUseWifi(deviceSn));
    }

    /**
     * 查询网关附近的wifi信息
     *
     * @param deviceSn
     * @return
     */
    @GetMapping("/findNearbyWifi")
    @Operation(summary = "查询网关附近的wifi信息")
    public Result<List<AroundWirelessNetwork>> findNearbyWifi(@RequestParam("deviceSn") String deviceSn) {
        return Result.success(deviceService.findNearbyWifi(deviceSn));
    }

    /**
     * 连接wifi
     *
     * @param modifyWirelessNetwork
     */
    @PostMapping("/connectWifi")
    @Operation(summary = "连接wifi")
    public Result connectWifi(@RequestBody @Validated ModifyWirelessNetwork modifyWirelessNetwork) {
        deviceService.connectWifi(modifyWirelessNetwork);
        return Result.success();
    }

    // 设置蜂窝网络
    @GetMapping("/setCellularNetwork")
    @Operation(summary = "设置蜂窝网络")
    public Result setCellularNetwork(@Parameter( name = "deviceSn", required = true, description = "设备sn") @RequestParam("deviceSn")  String deviceSn,@Parameter( name = "status", required = true, description = "开启关闭") @RequestParam("status") boolean status){
        deviceService.setCellularNetwork(deviceSn,status);
        return Result.success();
    }

    // 查询蜂窝网络
    @GetMapping("/findCellularNetwork")
    @Operation(summary = "查询蜂窝网络")
    public Result<Boolean> findCellularNetwork(@Parameter( name = "deviceSn", required = true, description = "设备sn")  @RequestParam("deviceSn") String deviceSn){

        return Result.success(deviceService.findCellularNetwork(deviceSn));
    }

    /**
     * 配件状态检测
     *
     * @param deviceSn
     * @return
     */
    @GetMapping("/findAccessoryStatus")
    @Operation(summary = "配件状态检测")
    public Result<AccessoryStatusDetectionSumReq> findAccessoryStatus(@RequestParam("deviceSn") String deviceSn, @RequestParam("pageNo") Integer pageNo, @RequestParam("pageSize") Integer pageSize) {
        return Result.success(deviceService.findAccessoryStatus(deviceSn,pageNo,pageSize));
    }

}

